package service

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/go-resty/resty/v2"
	"log"
	"net/http"
	"tianlian-ttc/internal/app/api/model"
	"time"
)

// TaskService 任务服务
type TaskService struct {
	client *resty.Client
	config *TaskConfig
}

// TaskConfig 任务配置
type TaskConfig struct {
	BaseURL       string // 基础URL
	SourceId      string
	DestinationId string
}

// logRequest logs resty request details
func logRequest(c *resty.Client, r *resty.Response) error {
	req := r.Request

	// Log request
	log.Printf("[Resty Request] %s %s\n", req.Method, req.URL)
	log.Printf("Headers: %v\n", req.Header)

	// Log request body if it exists
	if req.Body != nil {
		bodyBytes, err := json.Marshal(req.Body)
		if err == nil {
			var prettyJSON bytes.Buffer
			if err := json.Indent(&prettyJSON, bodyBytes, "", "  "); err == nil {
				log.Printf("Request Body: %s\n", prettyJSON.String())
			}
		}
	}

	// Log request parameters
	if len(req.QueryParam) > 0 {
		log.Printf("Query Params: %v\n", req.QueryParam)
	}
	if len(req.FormData) > 0 {
		log.Printf("Form Data: %v\n", req.FormData)
	}
	if len(req.PathParams) > 0 {
		log.Printf("Path Params: %v\n", req.PathParams)
	}

	// Log response
	log.Printf("[Resty Response] Status: %d\n", r.StatusCode())
	log.Printf("Headers: %v\n", r.Header())

	if len(r.Body()) > 0 {
		var prettyJSON bytes.Buffer
		if err := json.Indent(&prettyJSON, r.Body(), "", "  "); err == nil {
			log.Printf("Response Body: %s\n", prettyJSON.String())
		} else {
			log.Printf("Response Body: %s\n", string(r.Body()))
		}
	}

	return nil
}

// NewTaskService 创建任务服务实例
func NewTaskService(config *TaskConfig) *TaskService {

	client := resty.New()
	client.SetBaseURL(config.BaseURL)
	client.SetHeader("Content-Type", "application/json")

	// Enable request/response debug info
	client.SetDebug(true)

	// 设置重试策略
	client.SetRetryCount(3)
	client.SetRetryWaitTime(5 * time.Second)

	// Add logging middleware
	client.OnAfterResponse(logRequest)

	return &TaskService{
		client: client,
		config: config,
	}
}

// ApplyTask 申请任务
func (s *TaskService) ApplyTask(req *model.TaskRequest) (*model.Response, error) {
	req.Originator = s.config.SourceId
	req.Recipient = s.config.DestinationId
	if req.PlanList[0].Satellite == "xr7" {
		req.PlanList[0].Satellite = "XR07"
	}
	if req.PlanList[0].Satellite == "SJY01" {
		req.PlanList[0].Satellite = "SJY-01"
	}
	resp, err := s.client.R().
		SetBody(req).
		Post("/out/station/task/apply")

	if err != nil {
		return nil, fmt.Errorf("failed to send task application: %v", err)
	}

	var response model.Response
	if err := json.Unmarshal(resp.Body(), &response); err != nil {
		return nil, fmt.Errorf("failed to parse response: %v", err)
	}

	return &response, nil
}

// CancelTask sends a task cancellation request to the task service
func (s *TaskService) CancelTask(req *model.TaskCancelRequest) error {
	req.Originator = s.config.SourceId
	req.Recipient = s.config.DestinationId
	if req.PlanList[0].Satellite == "xr7" {
		req.PlanList[0].Satellite = "XR07"
	}
	if req.PlanList[0].Satellite == "SJY01" {
		req.PlanList[0].Satellite = "SJY-01"
	}
	resp, err := s.client.R().
		SetBody(req).
		Post("/out/station/task/cancel")

	if err != nil {
		return fmt.Errorf("failed to send task cancellation request: %v", err)
	}

	if resp.StatusCode() != http.StatusOK {
		return fmt.Errorf("task cancellation request failed with status code: %d, body: %s",
			resp.StatusCode(), string(resp.Body()))
	}

	return nil
}

// QueryIdleArc sends a request to query idle arcs
func (s *TaskService) QueryIdleArc(req *model.IdleArcQueryRequest) (*model.IdleArcQueryResponse, error) {
	req.Originator = s.config.SourceId
	req.Recipient = s.config.DestinationId
	if req.Satellite == "xr7" {
		req.Satellite = "XR07"
	}
	if req.Satellite == "SJY01" {
		req.Satellite = "SJY-01"
	}
	resp, err := s.client.R().
		SetBody(req).
		Post("/out/station/task/idleArc/query")

	if err != nil {
		return nil, fmt.Errorf("failed to send idle arc query request: %v", err)
	}

	if resp.StatusCode() != http.StatusOK {
		return nil, fmt.Errorf("idle arc query request failed with status code: %d, body: %s",
			resp.StatusCode(), string(resp.Body()))
	}

	var response model.IdleArcQueryResponse
	if err := json.Unmarshal(resp.Body(), &response); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response: %v", err)
	}

	return &response, nil
}
